﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using Axxx_sprial;
using ConfigSaver;
using Update;
using System.Management;

namespace Axxx_Sprial
{

    //[assembly: AssemblyVersion("1.0.0.0")]
    //[assembly: AssemblyFileVersion("1.0.0.0")]
    //static class Program
    //{
    //    /// <summary>
    //    /// 应用程序的主入口点。
    //    /// </summary>
    //    [STAThread]
    //    static void Main()
    //    {
    //        if (checkUpdateLoad())
    //        {
    //            Application.Exit();
    //            return;
    //        }
    //        Application.EnableVisualStyles();
    //        Application.SetCompatibleTextRenderingDefault(false);
    //        Application.Run(new FrmMain());
    //    }

    //    public static bool checkUpdateLoad()
    //    {
    //        bool result = false;
    //        SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "Axxx_Sprial");
    //        try
    //        {
    //            if (app.IsUpdate && MessageBox.Show("检查到新版本，是否更新？", "版本检查", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    //            {
    //                string path = Application.StartupPath.Replace("program", "");
    //                System.Diagnostics.Process process = new System.Diagnostics.Process();
    //                process.StartInfo.FileName = "AutoUpdate.exe";
    //                process.StartInfo.WorkingDirectory = path;//要掉用得exe路径例如:"C:\windows";               
    //                process.StartInfo.CreateNoWindow = true;
    //                process.Start();

    //                result = true;
    //            }
    //            else
    //            {
    //                result = false;
    //            }
    //        }
    //        catch (Exception ex)
    //        {
    //            MessageBox.Show(ex.Message);
    //            result = false;
    //        }
    //        return result;
    //    }
    //}

    struct Sprial_Data
    {
        public static int Check_bit = 0;//校验位默认为无校验
        public static int Data_bit = 2;//数据位默认为8
        public static int Stop_bit = 0;  //停止位默认为1    
    }

    struct Receive_Data
    {
        public int DeviceCode;
        public int FunctionCode;
        public int ByteCount;
    }

    struct Send_Data
    {
        public int DeviceCode;
        public int FunctionCode;
        public int Address;
        public int Data;
        public static int button1_flag = 0;//发送区1标志位,目的是为了不重复校验crc
        public static int button2_flag = 0;//发送区2标志位
        public static int button3_flag = 0;//发送区3标志位
    }
    struct Loop_send
    {
        //定时发送标志位
        public static int checkBox_LoopSend_flag = 0;
        public static int checkBox_LoopSend1_flag = 0;
        public static int checkBox_LoopSend2_flag = 0;
        public static int checkBox_LoopSend3_flag = 0;
    }
    struct CRC_x
    {
        //定义全局变量crc
        public static int uchCRCHi;
        public static int uchCRCLo;
        public static int uchCRC_8;

        public static int uchCRC_H16 = 0;

        public static int uchCRC_L16 = 0;   //crc_16

        public static Int32 uchCRC_SUM = 0;//总加和

        public static Int32 uchCRC_32 = 0;//uchCRC_32

        public static int uchCRCHi1;    //crc_32
        public static int uchCRCHi2;    //crc_32
        public static int uchCRCLo1;    //crc_32
        public static int uchCRCLo2;    //crc_32
        public static Int32 uchCRC_XOR = 0;//yihuo


        public static int sum_flag;
        public static int CRC_H16_flag = 0xff;
        public static int CRC_L16_flag = 0xff;
        public static int CRC_8_flag = 0xff;        //CRC_8
        public static Int32 CRC_SUM_flag = 0xff;    //总加和
        public static Int32 CRC_32_H_flag = 0xffff; //uchCRC_32
        public static Int32 CRC_32_L_flag = 0xffff; //uchCRC_32  
    }



    public partial class Form1 : Form
    {

        Configg cfg;
        byte[] buff = new byte[1024];
        public static bool showflag = true;



        private Queue<double> dataQueue = new Queue<double>(100);
        private Queue<double> dataQueue1 = new Queue<double>(100);
        private int curValue = 0;
        private int curValue1 = 0;
        private int num = 5;//每次删除增加几个点

        private void timer1_Tick(object sender, EventArgs e)//启动窗体加载示波器曲线
        {

            UpdateQueueValue();
            UpdateQueue1Value();
            this.chart1.Series[0].Points.Clear();
            this.chart1.Series[1].Points.Clear();
            for (int i = 0; i < dataQueue.Count; i++)
            {
                this.chart1.Series[0].Points.AddXY((i + 1), dataQueue.ElementAt(i));
                this.chart1.Series[1].Points.AddXY((i + 1), dataQueue1.ElementAt(i));
            }
        }
        private void button_from_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled == true)
            { timer1.Enabled = false; }
            else { timer1.Enabled = true; }
        }

        //更新队列中的值
        private void UpdateQueueValue()
        {

            if (dataQueue.Count > 100)
            {
                //先出列
                for (int i = 0; i < num; i++)
                {
                    dataQueue.Dequeue();
                }
            }
            if (false)
            {
                Random r = new Random();
                for (int i = 0; i < num; i++)
                {
                    dataQueue.Enqueue(r.Next(0, 100));
                }
            }
            if (false)
            {
                for (int i = 0; i < num; i++)
                {
                    //对curValue只取[0,360]之间的值
                    curValue = curValue % 360;
                    //对得到的正玄值，放大50倍，并上移50
                    dataQueue.Enqueue((50 * Math.Sin(curValue * Math.PI / 180)) + 50);
                    curValue = curValue + 10;
                }
            }
        }
        private void UpdateQueue1Value()
        {

            if (dataQueue1.Count > 100)
            {
                //先出列
                for (int i = 0; i < num; i++)
                {
                    dataQueue1.Dequeue();
                }
            }

        }


        Receive_Data ReceiveData = new Receive_Data();
        Send_Data SendData = new Send_Data();
        System.Timers.Timer ReceiveOverTimer = new System.Timers.Timer(10);   //实例化Timer类，设置间隔时间为100毫秒； 串口接收超时定时器
        System.Timers.Timer Looptimer = new System.Timers.Timer(50);   //实例化Timer类，设置初始间隔时间为500毫秒； 串口循环发送定时器
        System.Timers.Timer Looptimer1 = new System.Timers.Timer(500);
        System.Timers.Timer Looptimer2 = new System.Timers.Timer(500);
        System.Timers.Timer Looptimer3 = new System.Timers.Timer(500);

        public Form1()
        {
            InitializeComponent();
            this.Initialize();
           

        }

        // 初始化数据      
        private void Initialize()
        {

            ReceiveOverTimer.Elapsed += new System.Timers.ElapsedEventHandler(ReceiveTimeOut); //到达时间的时候执行事件；   
            ReceiveOverTimer.AutoReset = true;   //设置是执行一次（false）还是一直执行(true)；   
            Looptimer.Elapsed += new System.Timers.ElapsedEventHandler(LoopTimeOut); //到达时间的时候执行事件；   
            Looptimer.AutoReset = true;   //设置是执行一次（false）还是一直执行(true)；

            Looptimer1.Elapsed += new System.Timers.ElapsedEventHandler(LoopTimeOut1);
            Looptimer1.AutoReset = true;
            Looptimer2.Elapsed += new System.Timers.ElapsedEventHandler(LoopTimeOut2);
            Looptimer2.AutoReset = true;
            Looptimer3.Elapsed += new System.Timers.ElapsedEventHandler(LoopTimeOut3);
            Looptimer3.AutoReset = true;
            comboBox1_Function.SelectedIndex = 1;//modbus功能码默认为写数据
            comboBox_Function.SelectedIndex = 0;//modbus功能码默认为读数据

            //实时显示时钟
            new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        text_TIME1.BeginInvoke(new MethodInvoker(() => text_TIME1.Text = DateTime.Now.ToString()));
                    }
                    catch { }
                    Thread.Sleep(1000);
                }
            }) { IsBackground = true }.Start();
            //创建一个新的线程

            GetSerialLstTbl();//扫描串口
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            //    timer2.Enabled = true;


        }
        public Dictionary<string, string> dicClient = new Dictionary<string, string>();

        //扫描串口(在主循环中进行)
        private void GetSerialLstTbl()
        {
            //清除comboBoxEx显示         
            SerialPortComboBox.Items.Clear();

            //获取串口列表
            string[] serialLst = SerialPort.GetPortNames();
            if (serialLst.Length > 0)
            {
                //取串口列表进行排序
                Array.Sort(serialLst);
                //将串口列表输出到comboBoxEx

                SerialPortComboBox.Items.AddRange(serialLst);
                SerialPortComboBox.SelectedIndex = 0;//
                // SerialPortComboBox.SelectedIndex = SerialPortComboBox.Items.Count - 1;

                //    //显示所有串口号方法2：
                //    ////获取当前PC机上的所有串口  nice methods to browse all available ports;
                //    //string[] ports = SerialPort.GetPortNames();
                //    ////将获得的所有串口绑定到combobox控件  add all port names to the comboBox;
                //    //foreach (string port in ports)
                //    //{
                //    //    Stop_bitcomboBox.Items.Add(port);
                //    //}

            }
            

        }

        //com全称显示
        private void SerialPortComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            foreach (string str in dicClient.Keys)
            {
                if (SerialPortComboBox.Text.Contains(str))
                {
                    label22.Text = dicClient[str];

                }

            }
        }

        //刷新串口
        private void button5_Click(object sender, EventArgs e)
        {

            SerialPortComboBox.Items.Clear();
            for (int x = 0; x < 20; x++)
            {
                try
                {
                    if (serialPort1.IsOpen) serialPort1.Close();
                    serialPort1.PortName = "COM" + x.ToString();
                    serialPort1.Open();
                    SerialPortComboBox.Items.Add(serialPort1.PortName);
                    SerialPortComboBox.SelectedIndex = SerialPortComboBox.Items.Count - 1;
                }
                catch//(Exception ee)
                {
                    //MessageBox.Show(ee.Message);
                }
            }
        }



        public const int WM_DEVICE_CHANGE = 0x219;             //设备改变           
        public const int DBT_DEVICEARRIVAL = 0x8000;          //设备插入
        public const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004; //设备移除
        ////串口热插拔检测
        //protected override void WndProc(ref Message m)
        //{
        //    if (m.Msg == WM_DEVICE_CHANGE)        // 捕获USB设备的拔出消息WM_DEVICECHANGE
        //    {
        //        switch (m.WParam.ToInt32())
        //        {
        //            case DBT_DEVICE_REMOVE_COMPLETE:    // USB拔出


        //                if (SerialPortComboBox.Items.Contains(serialPort1.PortName))//如果选择框中包含插入的串口，拔出串口时，关闭串口
        //                {

        //                    if (serialPort1.IsOpen) //break;//串口正在使用则不操作
        //                    { SerialStatusButton_Click_1("usbremove", new EventArgs()); }

        //                    else //从端口移除
        //                    { this.SerialPortComboBox.Items.Remove(serialPort1.PortName); }

        //                    //// GetSerialLstTbl();

        //                    SerialStatusButton.Text = "打开";
        //                    SerialPortComboBox.Enabled = true;//串口号能按
        //                    BaudRateComboBox.Enabled = true;//波特率能按                         
        //                    Check_bitcomboBox.Enabled = true;//校验位按钮可以按
        //                    Stop_bitcomboBox.Enabled = true;//停止位按钮可以按
        //                    Data_bitcomboBox.Enabled = true;//数据位按钮可以按
        //                    StatusText1.Text = "串口关闭。";
        //                    button_Send.Enabled = false;
        //                    button_from.Enabled = false;
        //                    button4.Enabled = false;//
        //                    button_SaveToTxt.Enabled = false;
        //                    button11.Enabled = false;//清空显示
        //                    button_show_on_off.Enabled = false;
        //                    SerialPortComboBox.SelectedIndex = 0;

        //                }
        //                break;
        //            // USB插入获取对应串口名称
        //            case DBT_DEVICEARRIVAL:
        //                if (serialPort1.IsOpen) break;//串口正在使用则不操作
        //                GetSerialLstTbl(); break;                //设备改变时重新获取串口列表
        //        }

        //    }

        //    base.WndProc(ref m);
        //}
        //自动清   textBox11
      
        private void RichtextBox_Recive_clear(object sender, EventArgs e)
        {
           
            int count = this.RichtextBox_Recive.Lines.GetUpperBound(0);//获取行号（15行满屏）

            if (Auto_clear_checkBox3.Checked == true)
            {
                if (count < 0)
                {
                    return;
                }
                if (count > 15)
                {

                    RichtextBox_Recive.Clear();

                }
            }

           
        }

        //串口状态指示灯1
        private void SerialStatusButton_Click_1(object sender, EventArgs e)
        {
            Thread.Sleep(10);

            if (!serialPort1.IsOpen)
            {
                Thread.Sleep(10);
                SerialPortOpen();
                if (serialPort1.IsOpen)
                {
                    this.pictureBox1.Image = Axxx_sprial.Properties.Resources.绿;
                   
                }

            }
            else
            {
                Thread.Sleep(10);
                SerialPortClose();
                // GetSerialLstTbl();
                if (!serialPort1.IsOpen)
                {
                    this.pictureBox1.Image = Axxx_sprial.Properties.Resources.红;
                }
            }
        }
        //串口状态指示灯2
        void show_led()
        {
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.灰;
            Thread.Sleep(500);
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.绿;
        }



        //保存参数 
        private void Form1_Load(object sender, EventArgs e)
        {
            BaudRateComboBox.SelectedIndex = 3;
            Data_bitcomboBox.SelectedIndex = 2;
            Stop_bitcomboBox.SelectedIndex = 0;
            Check_bitcomboBox.SelectedIndex = 0;
            cfg = new Configg(@"c:User\public\UserConfig", this, true);
            //保存文本内容
            cfg.Add("", textBox_send1, "");
            cfg.Add("", textBox_send2, "");
            cfg.Add("", textBox_send3, "");
            cfg.Add("", textBox_send4, "");
            cfg.Add("", textBox3, "AA");
            cfg.Add("", textBox1, "AA");
            cfg.Add("", txtServer, "192.168.1.252");//记录ip地址
            cfg.Add("", txtPort, "6666");//记录端口号

            //保存参数设置
            cfg.Add("", BaudRateComboBox, 3);
            cfg.Add("", Data_bitcomboBox, 2);
            cfg.Add("", Stop_bitcomboBox, 0);
            cfg.Add("", Check_bitcomboBox, 0);
            cfg.Add("", Serive_type, 0);//记录服务模式
            //textBox11.SelectionColor = cd.Color;
            cfg.LoadConfig();//加载配置文件

            // Control.CheckForIllegalCrossThreadCalls = false;//服务端
            // Control.CheckForIllegalCrossThreadCalls = false;//客户端

        }

        string a = "";
        string b = "";
        //打开串口
        void SerialPortOpen()
        {

            try
            {
                serialPort1.PortName = SerialPortComboBox.SelectedItem.ToString();           
                serialPort1.BaudRate = int.Parse(BaudRateComboBox.SelectedItem.ToString());//选择波特率             
                switch (Stop_bitcomboBox.SelectedIndex)//停止位
                {
                    case 0: serialPort1.StopBits = StopBits.One; a = "1"; break;//1个停止位
                    case 1: serialPort1.StopBits = StopBits.OnePointFive; a = "1.5"; break;//1.5个停止位
                    case 2: serialPort1.StopBits = StopBits.Two; a = "2"; break;//2个停止位                                                                               //case 3: serialPort1.StopBits = StopBits.None; a = "None"; break;//无停止位
                    default:
                        serialPort1.StopBits = StopBits.One; break;
                };
                switch (Data_bitcomboBox.SelectedIndex)//数据位
                {
                    case 0: serialPort1.DataBits = 6; break;//6
                    case 1: serialPort1.DataBits = 7; ; break;//7
                    case 2: serialPort1.DataBits = 8; break;//8
                    default:
                        Sprial_Data.Data_bit = 0; break;
                };

                switch (Check_bitcomboBox.SelectedIndex)//校验位
                {
                    case 0: serialPort1.Parity = Parity.None; b = "无校验"; break;//无校验
                    case 1: serialPort1.Parity = Parity.Odd; b = "奇校验"; break;//奇校验
                    case 2: serialPort1.Parity = Parity.Even; b = "偶校验"; break;//偶校验
                    case 3: serialPort1.Parity = Parity.Space; b = "空格校验"; break;//空格校验
                    case 4: serialPort1.Parity = Parity.Mark; b = "Mark校验"; break;//MARK校验
                    default:
                        serialPort1.Parity = Parity.None; break;
                };
                serialPort1.Open();
                SerialStatusButton.Text = "关闭";   //打开串口之后
                SerialPortComboBox.Enabled = false; //串口号不能按

                StatusText1.Text = "状态：  " + "打开" + serialPort1.PortName + "成功  波特率:" + serialPort1.BaudRate.ToString() + "  停止位数:" + a.ToString() + "  " + b.ToString();//最下面显示串口状态
                button_Send.Enabled = true;
                button4.Enabled = true;
                button_from.Enabled = true;         //示波器启停
                button_SaveToTxt.Enabled = true;    //报文导出按钮
                button11.Enabled = true;            //清空接收按钮
                button_show_on_off.Enabled = true;  //停止显示按钮
               

            }
            catch (Exception ee)
            {
                MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                serialPort1.Close();
                SerialStatusButton.Text = "打开";
                SerialPortComboBox.Enabled = true;//串口号能按
                BaudRateComboBox.Enabled = true;//波特率能按

                StatusText1.Text = "串口关闭。";
                if ((checkBox_LoopSend1.Checked == true) || (checkBox_LoopSend2.Checked == true) || (checkBox_LoopSend3.Checked == true))
                {
                    Looptimer.Stop();
                    Looptimer1.Stop();
                    Looptimer2.Stop();
                    Looptimer3.Stop();
                    checkBox_LoopSend1.Checked = false;
                    checkBox_LoopSend2.Checked = false;
                    checkBox_LoopSend3.Checked = false;
                }
                ReceiveOverTimer.Stop();
            }

        }
        //关闭串口
        void SerialPortClose()
        {
            try
            { //2021-03-30 修改增加此处判断

                if (serialPort1.IsOpen) serialPort1.Close();
                ReceiveOverTimer.Stop();
                SerialStatusButton.Text = "打开";
                SerialPortComboBox.Enabled = true;


                StatusText1.Text = "串口关闭。";
                button_Send.Enabled = false;
                button_from.Enabled = false;
                button4.Enabled = false;//
                button_SaveToTxt.Enabled = false;
                button11.Enabled = false;//清空显示
                button_show_on_off.Enabled = false;
                if (checkBox_LoopSend1.Checked == true)
                {
                    Looptimer1.Stop();
                    checkBox_LoopSend1.Checked = false;
                }
                if (checkBox_LoopSend2.Checked == true)
                {
                    Looptimer2.Stop();
                    checkBox_LoopSend2.Checked = false;
                }
                if (checkBox_LoopSend3.Checked == true)
                {
                    Looptimer3.Stop();
                    checkBox_LoopSend3.Checked = false;
                }
            }
            catch (Exception)
            { }
          

        }

        //波特率改变了重新初始化波特率
        private void BaudRateComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.BaudRate = int.Parse(BaudRateComboBox.SelectedItem.ToString());//选择波特率 
            StatusText1.Text = "状态：  " + "打开" + serialPort1.PortName + "成功  波特率:" + serialPort1.BaudRate.ToString() + "  停止位数:" + a.ToString() + "  " + b.ToString();//最下面显示串口状态

        }
        //校验位发生了变化
        private void Check_bitcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {

            // string b = "";
            switch (Check_bitcomboBox.SelectedIndex)//校验位
            {
                case 0: serialPort1.Parity = Parity.None; b = "无校验"; break;//无校验
                case 1: serialPort1.Parity = Parity.Odd; b = "奇校验"; break;//奇校验
                case 2: serialPort1.Parity = Parity.Even; b = "偶校验"; break;//偶校验
                case 3: serialPort1.Parity = Parity.Space; b = "空格校验"; break;//空格校验
                case 4: serialPort1.Parity = Parity.Mark; b = "Mark校验"; break;//MARK校验
                default:
                    serialPort1.Parity = Parity.None; break;
            };
            StatusText1.Text = "状态：  " + "打开" + serialPort1.PortName + "成功  波特率:" + serialPort1.BaudRate.ToString() + "  停止位数:" + a.ToString() + "  " + b.ToString();//最下面显示串口状态
        }
        //停止位变化了
        private void Stop_bitcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // string a = "";
            switch (Stop_bitcomboBox.SelectedIndex)//停止位
            {
                case 0: serialPort1.StopBits = StopBits.One; a = "1"; break;//1个停止位
                case 1: serialPort1.StopBits = StopBits.OnePointFive; a = "1.5"; break;//1.5个停止位
                case 2: serialPort1.StopBits = StopBits.Two; a = "2"; break;//2个停止位        
                //case 3: serialPort1.StopBits = StopBits.None;       a = "None"; break;//无停止位
                default:
                    serialPort1.StopBits = StopBits.One; break;
            };

            StatusText1.Text = "状态：  " + "打开" + serialPort1.PortName + "成功  波特率:" + serialPort1.BaudRate.ToString() + "  停止位数:" + a.ToString() + "  " + b.ToString();//最下面显示串口状态
        }
        //数据位变化了
        private void Data_bitcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (Data_bitcomboBox.SelectedIndex)//数据位
            {
                case 0: serialPort1.DataBits = 6; break;//6
                case 1: serialPort1.DataBits = 7; ; break;//7
                case 2: serialPort1.DataBits = 8; break;//8
                default:
                    Sprial_Data.Data_bit = 0; break;
            };
            StatusText1.Text = "状态：  " + "打开" + serialPort1.PortName + "成功  波特率:" + serialPort1.BaudRate.ToString() + "  停止位数:" + a.ToString() + "  " + b.ToString();//最下面显示串口状态
        }


    


        //显示停止/开始
        private void button_show_on_off_click(object sender, EventArgs e)
        {

            if (Form1.showflag)
            {
                button_show_on_off.Text = "开始显示";
                Form1.showflag = !Form1.showflag; //初始值为1
            }
            else
            {
                button_show_on_off.Text = "停止显示";
                Form1.showflag = !Form1.showflag; //初始值为1
            }
        }
        int ReceiveCount = 0;
        //CRC校验正确自动回复数据
        void CRC_Check(Byte[] DataReceive, int ReceiveCount)
        {
            int uIndex; /* CRC循环中的索引 */
            int pLength;
            CRC_x.uchCRCHi = 0xFF; /* 高CRC字节初始化 */
            CRC_x.uchCRCLo = 0xFF; /* 低CRC 字节初始化 */
            pLength = 0;
            if (ReceiveCount > 4)//最少接收个数限制
            {
                while (pLength < (ReceiveCount - 2)) /* 传输消息缓冲区 */
                {
                    uIndex = CRC_x.uchCRCHi ^ DataReceive[pLength]; /* 计算CRC */
                    CRC_x.uchCRCHi = CRC_x.uchCRCLo ^ auchCRCHi[uIndex];
                    CRC_x.uchCRCLo = auchCRCLo[uIndex];
                    pLength++;
                }
                if ((DataReceive[ReceiveCount - 2] == CRC_x.uchCRCHi) && (DataReceive[ReceiveCount - 1] == CRC_x.uchCRCLo))
                {
                    this.Invoke(new EventHandler(DisplayText));
                    Thread.Sleep(Convert.ToInt32(timejiange.Text, 10));//自动回复数据时间间隔
                    this.Invoke(new EventHandler(button_Send_Click_1));
                }
            }
            // Array.Clear(DataReceive, 0, DataReceive.Length);
        }

        static int ReadBufferSize;//缓冲器待读取字节数
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            this.pictureBox3.Image = Axxx_sprial.Properties.Resources.灰;//收到数据闪灯
            Thread.Sleep(220);//延迟目的是因为串口接收下位机数据过来会有延迟，多等一会是为了等数据全部接收到
            ReceiveOverTimer.Start();

            if (serialPort1.IsOpen)//2021-03-30 修改增加此处判断
            {
                ReadBufferSize = serialPort1.BytesToRead;//缓冲器待读取字节数           
                serialPort1.Read(DataReceive, 0, ReadBufferSize);
            }

            //curvess(DataReceive);
            //this.Invoke(new EventHandler(DisplayText));    //括号内为绘制窗口的方法的委托，采用的是标准事件的委托
        }

        byte[] DataReceive = new byte[2048];//接收数据缓存
        //串口接收中断
        public void ReceiveTimeOut(object source, System.Timers.ElapsedEventArgs e)
        {

            this.pictureBox3.Image = Axxx_sprial.Properties.Resources.绿; //收到数据闪灯                      
            ReceiveOverTimer.Stop();
            ReceiveCount = ReadBufferSize;
            //判断CRC正确，自动回复
            if (radioButton3.Checked == true)
            {
                CRC_Check(DataReceive, ReceiveCount);
            }
            else if (radioButton4.Checked == true)
            {
                this.Invoke(new EventHandler(DisplayText));//调用显示函数
                Thread.Sleep(Convert.ToInt32(timejiange.Text, 10));//自动回复数据时间间隔
                this.Invoke(new EventHandler(button_Send_Click_1));
            }

            else if (ReceiveCount > 0)//最少接收个数限制（如果收到数据）
            {
                if (serialPort1.IsOpen)//2021-03-30 修改增加此处判断，作用防止串口在接收数据时关闭串口会卡死现象
                {
                    this.Invoke(new EventHandler(DisplayText));//调用显示函数
                }
            }
            Array.Clear(DataReceive, 0, DataReceive.Length);

        }

        int RowsCount = 0;
        //显示窗体
        private void DisplayText(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                this.pictureBox3.Image = Axxx_sprial.Properties.Resources.灰;
                Thread.Sleep(20);
                this.pictureBox3.Image = Axxx_sprial.Properties.Resources.绿;

                int a = 0;
                int b = 0;//数据1
                int c = 0;//数据2
                byte[] buffer = new byte[1024];
                string Readstr = "";
                string Readstr1 = "";//存放接收到数据
                string Readstr2 = "";//从第几字节解析

                //数据解析页面开关
                if (checkBox1_jiexi.Checked == true)
                {
                    for (int x = 0; x < ReceiveCount; x++)
                    {
                        Readstr1 += DataReceive[x].ToString("X2") + " ";
                    }

                    Readstr2 = textBox_Num.Text.ToString();

                    string Readstr3 = Readstr2.Replace(" ", "");
                    a = FuntionCode_CRC1(0, buffer, a, Readstr3);
                    int d = buffer[0];
                    //大端（低高）
                    if (radioButton1.Checked == true)
                    {
                        if (checkBox1.Checked == true)
                            b = (DataReceive[d] | (DataReceive[d + 1] << 8));

                        if (checkBox2.Checked == true)
                            c = (DataReceive[d + 2] | (DataReceive[d + 3] << 8));
                    }
                    else//小端（高低）
                    {
                        if (checkBox1.Checked == true)
                            b = (DataReceive[d + 1] | (DataReceive[d] << 8));
                        if (checkBox2.Checked == true)
                            c = (DataReceive[d + 3] | (DataReceive[d + 2] << 8));
                    }

                    dataGridView1.Rows.Add();
                    RowsCount++;
                    dataGridView1[0, RowsCount - 1].Value = RowsCount;//表格显示序号
                    dataGridView1[1, RowsCount - 1].Value = Readstr1;//表格显示接收数据
                    dataGridView1[2, RowsCount - 1].Value = DateTime.Now.ToString();//表格显示时间
                    dataGridView1[3, RowsCount - 1].Value = b;//表格显示数据1
                    dataGridView1[4, RowsCount - 1].Value = c;//表格显示数据2
                    dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;//滚动条滚到最底部位置                      

                    // chart1.Series[0].XValueMember = b.ToString();
                    // chart1.Series[0].YValueMembers =c.ToString();

                    dataQueue.Enqueue(b);//数据1
                    dataQueue1.Enqueue(c);//数据2


                }
                //选择16进制显示
                if (checkHexorChar.Checked == true)
                //  if ( 1== Sprial_Data.Checked_hex_flag)
                {
                    for (int x = 0; x < ReceiveCount; x++)
                    {
                        Readstr += DataReceive[x].ToString("X2") + " ";//转化有问题）
                    }
                }
                else //选择char型显示
                {
                    Readstr = System.Text.Encoding.ASCII.GetString(DataReceive);//byte型转字符串型
                }
                if (Form1.showflag)//显示开始/停止显示
                {
                    RichtextBox_Recive.SelectionColor = Color.Red;//字体颜色
                    RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + "接收:" + Readstr);  //添加文本                    
                    RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                    RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行
                    // this.serialPort1.DiscardInBuffer();//丢弃接收缓存区数据
                }
            }

            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();
                //if (serialPort1.IsOpen) serialPort1.Close();
                //SerialStatusButton.Text = "打开";
                //SerialPortComboBox.Enabled = true;
                //BaudRateComboBox.Enabled = true;
                //SerialPortScanButton.Enabled = true;
                StatusText1.Text = "串口关闭。";
                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }

        /* CRC 高位字节值表 */
        public byte[] auchCRCHi = {
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
                           };
        /* CRC低位字节值表*/
        public byte[] auchCRCLo = {
        0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
        0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
        0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
        0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
        0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
        0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
        0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
        0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
        0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
        0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
        0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
        0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
        0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
        0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
        0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
        0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
        0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
        0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
        0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
        0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
        0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
        0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
        0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
        0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
        0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
        0x43, 0x83, 0x41, 0x81, 0x80, 0x40
                           };
        public int crc16(byte[] puckMsg, int Length)
        {
            int uIndex;                    /* CRC循环中的索引 */
            int pLength = 0;
            CRC_x.uchCRCHi = 0xFF;         /* 高CRC字节初始化 */
            CRC_x.uchCRCLo = 0xFF;         /* 低CRC 字节初始化 */
            while (pLength < (Length - 2)) /* 传输消息缓冲区 */
            {
                uIndex = CRC_x.uchCRCHi ^ puckMsg[pLength]; /* 计算CRC */
                CRC_x.uchCRCHi = CRC_x.uchCRCLo ^ auchCRCHi[uIndex];
                CRC_x.uchCRCLo = auchCRCLo[uIndex];
                pLength++;
            }
            return (CRC_x.uchCRCHi << 8 | CRC_x.uchCRCLo);
        }
        // <summary>     /// CRC8位校验表     /// </summary>     
        private byte[] CRC8Table = new byte[] 
            {    0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
                157,195,33,127,252,162,64,30, 95,1,227,189,62,96,130,220,
                35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
                190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
                70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
                219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
                101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
                248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
                140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
                17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
                175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
                50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
                202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
                87,9,235,181,54,104,138,212,149,203, 41,119,244,170,72,22,
                233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
                116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53 };

        //CRC8
        public int CRC8(byte[] buffer, int Length)
        {
            int crc = 0;
            for (int j = 0; j < Length - 1; j++)
            {
                crc = CRC8Table[crc ^ buffer[j]];

            }
            CRC_x.uchCRC_8 = crc;
            return CRC_x.uchCRC_8;
        }

        //总加和
        public Int32 Sum(byte[] memorySpage, int Length)
        {
            int num = 0;
            for (int i = 0; i < Length - 1; i++)
            {
                num = (num + memorySpage[i]) % 0xffff;
            }
            memorySpage = BitConverter.GetBytes(num);

            CRC_x.uchCRC_SUM = num;
            return CRC_x.uchCRC_SUM;


        }

        protected ulong[] Crc32Table;
        //生成CRC32码表
        public void GetCRC32Table()
        {
            ulong Crc;
            Crc32Table = new ulong[256];
            int i, j;
            for (i = 0; i < 256; i++)
            {
                Crc = (ulong)i;
                for (j = 8; j > 0; j--)
                {
                    if ((Crc & 1) == 1)
                        Crc = (Crc >> 1) ^ 0xEDB88320;
                    else
                        Crc >>= 1;
                }
                Crc32Table[i] = Crc;
            }
        }


        public Int32 GetCRC32(byte[] bytes, int Length)
        {
            int iCount = Length;
            ulong crc = 0xFFFFFFFF;
            GetCRC32Table();

            for (uint i = 0; i < iCount - 4; i++)
            {
                crc = (crc >> 8) ^ Crc32Table[(crc & 0xFF) ^ bytes[i]];
            }
            ulong temp = crc ^ 0xFFFFFFFF;
            CRC_x.uchCRCHi1 = (byte)(temp >> 24);  //高位置
            CRC_x.uchCRCLo1 = (byte)(temp >> 16);  //低位置
            CRC_x.uchCRCHi2 = (byte)(temp >> 8);    //高位置
            CRC_x.uchCRCLo2 = (byte)(temp);         //低位置

            return (CRC_x.uchCRCHi1 << 24 | CRC_x.uchCRCHi2 << 16 | CRC_x.uchCRCLo1 << 8 | CRC_x.uchCRCLo2);
        }


        //CRC异或校验            
        public int GetXOR(byte[] Cmd, int Length)
        {

            int check = (byte)(Cmd[0] ^ Cmd[1]);
            for (int i = 2; i < Length - 1; i++)
            {
                check = (byte)(check ^ Cmd[i]);

            }
            CRC_x.uchCRC_XOR = check;
            return CRC_x.uchCRC_XOR;
        }

        //IndexNum：校验方式选择
        //byte[] buffa:校验完之后附加到之前的报文后面，并存放在这个数组里
        //  a：存放数据+校验的数组的大小
        //str：输入要转换的字符串
        //功能：
        //举例：将 010310600001转化为16进制在选择校验，之后得到的数据存放在大小为a的数组中
        public int FuntionCode_CRC1(int IndexNum, byte[] buffa, int a, string str)
        {
            int Num = 0;//存放校验后的值
            switch (IndexNum)
            {
                case 0://无校验
                    if (str.Length == 1)//要发送字符有1个
                    {
                        a = str.Length;
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))//要发送字符有偶数个
                    {
                        a = str.Length / 2;//有几对字符

                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }

                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))//要发送字符有奇数个
                    {
                        int i = 0;
                        a = (str.Length / 2 + 1);

                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }
                    if (Send_Data.button1_flag == 1)//清按键标志位
                    {
                        Send_Data.button1_flag = 0;

                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;

                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;

                    }

                    break;

                case 1://crc16校验低字节校验
                    comboBox_CRCFunction1.SelectedIndex = 0;//清除到无校验状态
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                        a = a + 2;
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几对字符
                        a = a + 2;

                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }

                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        int i = 0;
                        a = (str.Length / 2 + 1);
                        a = a + 2;

                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = crc16(buffa, a);
                    buffa[a - 2] = (byte)CRC_x.uchCRCHi;//a代表数组下标
                    buffa[a - 1] = (byte)CRC_x.uchCRCLo;

                    if (Send_Data.button1_flag == 1)//
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += (CRC_x.uchCRCLo.ToString("x2").ToUpper() + CRC_x.uchCRCHi.ToString("x2").ToUpper());
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += (CRC_x.uchCRCLo.ToString("x2").ToUpper() + CRC_x.uchCRCHi.ToString("x2").ToUpper());
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += (CRC_x.uchCRCLo.ToString("x2").ToUpper() + CRC_x.uchCRCHi.ToString("x2").ToUpper());
                    }
                    // 清除缓冲值
                    CRC_x.uchCRCHi = 0;
                    CRC_x.uchCRCLo = 0;
                    break;
                case 2:
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        a = a + 2;
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a = a + 2;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a = a + 2;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据

                    }


                    Num = crc16(buffa, a);
                    buffa[a - 1] = (byte)CRC_x.uchCRCHi;  //a代表数组下标
                    buffa[a - 2] = (byte)CRC_x.uchCRCLo;
                    if (Send_Data.button1_flag == 1)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRCHi.ToString("x2").ToUpper() + CRC_x.uchCRCLo.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRCHi.ToString("x2").ToUpper() + CRC_x.uchCRCLo.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRCHi.ToString("x2").ToUpper() + CRC_x.uchCRCLo.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRCHi = 0;
                    CRC_x.uchCRCLo = 0;

                    break;
                case 3://sum
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        a = a + 1;//+n是用来放校验位的
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a = a + 1;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a = a + 1;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = Sum(buffa, a);
                    buffa[a - 1] = (byte)CRC_x.uchCRC_SUM;//a代表数组下标


                    if (Send_Data.button1_flag == 1)
                    //  if (button1.Checked == true)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRC_SUM.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRC_SUM.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRC_SUM.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRC_SUM = 0;

                    break;

                case 4:
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;

                        a = a + 1;//+n是用来放校验位的
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);

                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a = a + 1;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a = a + 1;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = CRC8(buffa, a);
                    buffa[a - 1] = (byte)CRC_x.uchCRC_8;//a代表数组下标

                    if (Send_Data.button1_flag == 1)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRC_8.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRC_8.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRC_8.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRC_8 = 0;
                    break;
                case 5:
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        a += 4;
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a += 4;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a += 4;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = GetCRC32(buffa, a);
                    buffa[a - 4] = (byte)CRC_x.uchCRCHi1;//a代表数组下标
                    buffa[a - 3] = (byte)CRC_x.uchCRCLo1;//a代表数组下标
                    buffa[a - 2] = (byte)CRC_x.uchCRCHi2;//a代表数组下标
                    buffa[a - 1] = (byte)CRC_x.uchCRCLo2;//a代表数组下标

                    if (Send_Data.button1_flag == 1)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRCHi1 = 0;
                    CRC_x.uchCRCLo1 = 0;
                    CRC_x.uchCRCHi2 = 0;
                    CRC_x.uchCRCLo2 = 0;
                    break;
                case 6:
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        a += 4;
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a += 4;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a += 4;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = GetCRC32(buffa, a);
                    buffa[a - 4] = (byte)CRC_x.uchCRCHi2;//a代表数组下标
                    buffa[a - 3] = (byte)CRC_x.uchCRCLo2;//a代表数组下标
                    buffa[a - 2] = (byte)CRC_x.uchCRCHi1;//a代表数组下标
                    buffa[a - 1] = (byte)CRC_x.uchCRCLo1;//a代表数组下标
                    if (Send_Data.button1_flag == 1)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRCHi1.ToString("x2").ToUpper() + CRC_x.uchCRCHi2.ToString("x2").ToUpper() + CRC_x.uchCRCLo1.ToString("x2").ToUpper() + CRC_x.uchCRCLo2.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRCHi1 = 0;
                    CRC_x.uchCRCLo1 = 0;
                    CRC_x.uchCRCHi2 = 0;
                    CRC_x.uchCRCLo2 = 0;

                    break;
                case 7:
                    comboBox_CRCFunction1.SelectedIndex = 0;
                    comboBox_CRCFunction2.SelectedIndex = 0;
                    comboBox_CRCFunction3.SelectedIndex = 0;
                    comboBox_CRCFunction4.SelectedIndex = 0;
                    if (str.Length == 1)
                    {
                        a = str.Length;
                        a = a + 1;//+n是用来放校验位的
                        buffa[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 0))
                    {
                        a = str.Length / 2;//有几个“xx" 
                        a = a + 1;
                        for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                        }
                    }
                    else if ((str.Length > 1) & (str.Length % 2 == 1))
                    {
                        a = (str.Length / 2 + 1);
                        a = a + 1;
                        int i = 0;
                        for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                        {
                            buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                        }
                        buffa[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据
                    }


                    Num = GetXOR(buffa, a);
                    buffa[a - 1] = (byte)CRC_x.uchCRC_XOR;//a代表数组下标

                    if (Send_Data.button1_flag == 1)
                    {
                        Send_Data.button1_flag = 0;
                        textBox_send1.Text += CRC_x.uchCRC_XOR.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button2_flag == 1)
                    {
                        Send_Data.button2_flag = 0;
                        textBox_send2.Text += CRC_x.uchCRC_XOR.ToString("x2").ToUpper();
                    }
                    if (Send_Data.button3_flag == 1)
                    {
                        Send_Data.button3_flag = 0;
                        textBox_send3.Text += CRC_x.uchCRC_XOR.ToString("x2").ToUpper();
                    }
                    // 清除缓冲值
                    CRC_x.uchCRC_XOR = 0;

                    break;
                default:
                    Num = 0;
                    break;
            }
            return a;
        }

        //自定义函数处理字符串,把4个字符合成2个字符
        private byte Deal_str(string str, byte[] bufer)
        {
            if (str.Length == 1) //如果字符串只有1个字符   例如string="1"
            {
                //  textBox_send1_string_real = string.Format("{0:d2}", textBox_send1_string_real);

                bufer[0] = (byte)Convert.ToByte(str.Substring(0, 1), 16);
            }
            else //如果字符串>1个字符   liru string="12",string="12233"
            {
                if (str.Length % 2 == 0)  //如果字符串是偶数个按2位来截取转换为byte数据
                {
                    for (int i = 0; i < str.Length; i += 2)//循环遍历字符串来赋值给byte数组
                    {
                        bufer[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据
                    }
                }

                else //如果字符串字符个数是奇数，则按1位来截取转换为byte数据 例如:string="112",string="12223"  
                {//(a最小为3)textBox_send1_string_real.Length-1
                    int i = 0;
                    for (i = 0; i < str.Length - 1; i += 2)//循环遍历字符串来赋值给byte数组
                    {
                        bufer[i / 2] = (byte)Convert.ToByte(str.Substring(i, 2), 16);//按2位来截取转换为byte数据                                                                 
                    }
                    bufer[i / 2] = (byte)Convert.ToByte(str.Substring(i, 1), 16);//按两位截取完，剩下的按1位来截取转换为byte数据              
                }

            }
            return 1;
        }

        //文字滚动
        private void timerLoad_Tick(object sender, EventArgs e)
        {
            int Left_bianjie = 520;//（向左移动的最左边界）
            int Right_bianjie = 550;//最左边界在开始移动时的起始位置——向左移动时）
            timerLoad.Enabled = true;
            label22.Left = label22.Left - 1;

            if (label22.Right < Left_bianjie)//右
            {
                label22.Left = Right_bianjie;// this.Width;
                Thread.Sleep(400);
            }
            // pictureBox1.Image = getBitMapFile( Width,  Height);//画坐标
        }
        //原来的画曲线图用到的定时器


        /* modbus功能号 */
        int FuntionCode(int IndexNum)
        {
            int Num = 0;
            switch (IndexNum)
            {
                case 0:
                    Num = 0x03;
                    break;
                case 1:
                    Num = 0x10;
                    break;
                default:
                    Num = 0x05;
                    break;
            }
            return Num;
        }

        private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = true;
        }


        //modbus读数据帧发送
        private void button_Send_Click(object sender, EventArgs e)
        {
            byte[] buffc = new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 };
            CRC_x.uchCRCHi = 0;
            CRC_x.uchCRCLo = 0;
            try
            { //00 03 10 60 00 01 crc
                buffc[0] = (byte)Convert.ToInt32(textBox_Device.Text, 16);
                buffc[1] = (byte)FuntionCode(comboBox_Function.SelectedIndex);
                buffc[2] = (byte)(Convert.ToInt32(textBox_Address.Text, 16) / 256);
                buffc[3] = (byte)(Convert.ToInt32(textBox_Address.Text, 16) & 0x00ff);
                buffc[4] = (byte)(Convert.ToInt32(textBox_Data.Text, 16) / 256);
                buffc[5] = (byte)(Convert.ToInt32(textBox_Data.Text, 16) & 0x00ff);
                crc16(buffc, 8);
                buffc[6] = (byte)CRC_x.uchCRCHi;
                buffc[7] = (byte)CRC_x.uchCRCLo;

                SendData.DeviceCode = buffc[0];
                SendData.FunctionCode = buffc[1];
                SendData.Address = Convert.ToInt32(textBox_Address.Text, 16);//字符转16进制
                SendData.Data = Convert.ToInt32(textBox_Data.Text, 16);//字符转16进制
                /*1).转化为16进制。
                    2).大写X:ToString("X2")即转化为大写的16进制。
                    3).小写x:ToString("x2")即转化为小写的16进制。
                    4).2表示输出两位，不足的2位的前面补0,如 0x0A 如果没有2,就只会输出0xA
                */

                textBox_CRC.Text = CRC_x.uchCRCHi.ToString("x2").ToUpper() + CRC_x.uchCRCLo.ToString("x2").ToUpper();
                if (serialPort1.IsOpen)
                {
                    serialPort1.Write(buffc, 0, 8);//发送时候字符之间不加空格
                    string Sendstr = "发送:";
                    foreach (byte x in buffc)
                    {
                        Sendstr += x.ToString("x2").ToUpper() + " ";//显示出来加空格
                    }
                    RichtextBox_Recive.SelectionColor = Color.Blue;
                    RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + Sendstr);  //添加文本
                    RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                    RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行
                    //textBox11.SetSelected(textBox11.Items.Count - 1, true);
                }
                else
                {

                    Looptimer.Stop();
                    Looptimer1.Stop();
                    Looptimer2.Stop();
                    Looptimer3.Stop();
                    ReceiveOverTimer.Stop();
                    if (serialPort1.IsOpen) serialPort1.Close();
                    SerialStatusButton.Text = "打开";
                    SerialPortComboBox.Enabled = true;
                    BaudRateComboBox.Enabled = true;
                    SerialPortScanButton.Enabled = true;
                    StatusText1.Text = "串口关闭。";
                    button_Send.Enabled = false;
                    MessageBox.Show(this, "请打开串口", "提示");
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        //modbus写数据帧发送
        private void button7_Click(object sender, EventArgs e)
        {
            int length=0;
            string str;
            byte[] buffc = new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 };
          
           
            CRC_x.uchCRCHi = 0;
            CRC_x.uchCRCLo = 0;

            //组帧:
            //获取textBox_send1文本框的值
            str = textBox_send7.Text.ToString(); //textBox_send1为textBox控件的名称

            string textBox_send7_string_real = str.Replace(" ", "");//先替换其中的空格等

            int a = 1;
            byte[] buffer = new byte[1024];
           
            //发送16进制
             //计算要定义数组的长度值buff[a]。计算a的值
            a = FuntionCode_CRC1(0, buffer, a, textBox_send7_string_real);
                  
            try
            { //00 10 10 60 00 01 02 +数据内容  crc
                buffc[0] = (byte)Convert.ToInt32(textBox1_Device.Text, 16);
                buffc[1] = (byte)FuntionCode(1);
                buffc[2] = (byte)(Convert.ToInt32(textBox1_Address.Text, 16) / 256);
                buffc[3] = (byte)(Convert.ToInt32(textBox1_Address.Text, 16) & 0x00ff);
                buffc[4] = (byte)(Convert.ToInt32(textBox1_Data.Text, 16) / 256);
                buffc[5] = (byte)(Convert.ToInt32(textBox1_Data.Text, 16) & 0x00ff);
                buffc[6] = (byte)(2 * buffc[5]);//长度
                //textBox1_Len.Text = Encoding.Default.GetString(buffc);
               //计算要定义的buffd的长度
                length = 7 + 2 * buffc[5] + 2;
                
                byte[] buffd = new byte[length];//存放帧头+帧尾+校验好的数据,a为校验之后的数据
                //1.把buffc的数据拷贝到新定义的数组里，
                for (int i = 0; i < 7; ++i)
                {
                    buffd[0+i] = buffc[i];
                }
                //2.然后追加要发送的数据内容
                for (int i = 0; i < a; ++i)
                {
                    buffd[7 + i] = buffer[i];
                }

                crc16(buffd, length);
                buffd[length - 2] = (byte)CRC_x.uchCRCHi;
                buffd[length - 1] = (byte)CRC_x.uchCRCLo;


                //SendData.DeviceCode = buffc[0];
                //SendData.FunctionCode = buffc[1];
                //SendData.Address = Convert.ToInt32(textBox_Address.Text, 16);//字符转16进制
                //SendData.Data = Convert.ToInt32(textBox_Data.Text, 16);//字符转16进制
                ///*1).转化为16进制。
                //    2).大写X:ToString("X2")即转化为大写的16进制。
                //    3).小写x:ToString("x2")即转化为小写的16进制。
                //    4).2表示输出两位，不足的2位的前面补0,如 0x0A 如果没有2,就只会输出0xA
                //*/

                textBox1_CRC.Text = CRC_x.uchCRCHi.ToString("x2").ToUpper() + CRC_x.uchCRCLo.ToString("x2").ToUpper();
                if (serialPort1.IsOpen)
                {
                    serialPort1.Write(buffd, 0,  length);//发送时候字符之间不加空格
                    string Sendstr = "发送:";
                    foreach (byte x in buffd)
                    {
                        Sendstr += x.ToString("x2").ToUpper() + " ";//显示出来加空格
                    }
                    RichtextBox_Recive.SelectionColor = Color.Blue;
                    RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + Sendstr);  //添加文本
                    RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                    RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行
                    //textBox11.SetSelected(textBox11.Items.Count - 1, true);
                }
                else
                {

                    Looptimer.Stop();
                    Looptimer1.Stop();
                    Looptimer2.Stop();
                    Looptimer3.Stop();
                    ReceiveOverTimer.Stop();
                    if (serialPort1.IsOpen) serialPort1.Close();
                    SerialStatusButton.Text = "打开";
                    SerialPortComboBox.Enabled = true;
                    BaudRateComboBox.Enabled = true;
                    SerialPortScanButton.Enabled = true;
                    StatusText1.Text = "串口关闭。";
                    button_Send.Enabled = false;
                    MessageBox.Show(this, "请打开串口", "提示");
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }










        }


        //循环发送超时处理
        public void LoopTimeOut(object source, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new EventHandler(LoopSend));
        }
        //循环发送定时器1超时处理
        public void LoopTimeOut1(object source, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new EventHandler(LoopSend));
        }
        //循环发送定时器2超时处理
        public void LoopTimeOut2(object source, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new EventHandler(LoopSend));

        }
        //循环发送定时器3超时处理
        public void LoopTimeOut3(object source, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new EventHandler(LoopSend));
        }
        //循环发送开关（自定义函数，被上面调用）
        void LoopSend(object sender, EventArgs e)
        {
            if (Loop_send.checkBox_LoopSend1_flag == 1)
            {
                button_Send_Click_1(null, null);
            }
            if (Loop_send.checkBox_LoopSend2_flag == 1)
            {
                button_Send_Click_2(null, null);
            }
            if (Loop_send.checkBox_LoopSend3_flag == 1)
            {
                button_Send_Click_3(null, null);
            }
        }

        //发送区1定时发送
        private void checkBox_LoopSend_CheckedChanged1(object sender, EventArgs e)
        {

            if (checkBox_LoopSend1.Checked == false)//定时发按钮没有按下
            {
                Loop_send.checkBox_LoopSend1_flag = 0;//定时按钮没被选中，定时发送标志位置0             
               // Looptimer1.Stop();
                comboBox_SendTimer1.Enabled = true;//定时时间输入框打开（可以随意设定时间）
            }
            else
            {
                Loop_send.checkBox_LoopSend1_flag = 1;//按下定时发送按钮，定时发送标志位置1 
                Looptimer1.Start();
                Looptimer1.Interval = Convert.ToDouble(comboBox_SendTimer1.Text.ToString());//间隔时间
                comboBox_SendTimer1.Enabled = false;//定时时间输入框关闭（禁止设定时间）
                this.Invoke(new EventHandler(button_Send_Click_1));
            }
        }
        //发送区2定时发送
        private void checkBox_LoopSend_CheckedChanged2(object sender, EventArgs e)
        {
            if (checkBox_LoopSend2.Checked == false)
            {
                Loop_send.checkBox_LoopSend2_flag = 0;//定时按钮没被选中，定时发送标志位置0             
                Looptimer2.Stop();
                comboBox_SendTimer2.Enabled = true;//定时时间输入框打开（可以随意设定时间）

            }
            else
            {
                Loop_send.checkBox_LoopSend2_flag = 1;//按下定时发送按钮，定时发送标志位置1
                //Looptimer2.Start();
                Looptimer2.Interval = Convert.ToDouble(comboBox_SendTimer2.Text.ToString());//间隔时间
                comboBox_SendTimer2.Enabled = false;
                this.Invoke(new EventHandler(button_Send_Click_2));
            }
        }
        //发送区3定时发送
        private void checkBox_LoopSend_CheckedChanged3(object sender, EventArgs e)
        {
            if (checkBox_LoopSend3.Checked == false)
            {
                Loop_send.checkBox_LoopSend3_flag = 0;//定时按钮没被选中，定时发送标志位置0             
                Looptimer3.Stop();
                comboBox_SendTimer3.Enabled = true;//定时时间输入框打开（可以随意设定时间）
            }
            else
            {
                Loop_send.checkBox_LoopSend3_flag = 1;//按下定时发送按钮，定时发送标志位置1
                //Looptimer3.Start();
                Looptimer3.Interval = Convert.ToDouble(comboBox_SendTimer3.Text.ToString());//间隔时间
                comboBox_SendTimer3.Enabled = false;
                this.Invoke(new EventHandler(button_Send_Click_3));
            }
        }

        //DataGridView显示的数据直接导出Excel
        public void DataToExcel(DataGridView m_DataView)
        {
            SaveFileDialog kk = new SaveFileDialog();
            kk.Title = "保存EXECL文件";
            kk.Filter = "EXECL文件(*.xls) |*.xls |所有文件(*.*) |*.*";
            kk.FilterIndex = 1;
            if (kk.ShowDialog() == DialogResult.OK)
            {
                string FileName = kk.FileName;// +".xls";
                if (File.Exists(FileName))
                    File.Delete(FileName);
                FileStream objFileStream;
                StreamWriter objStreamWriter;
                string strLine = "";
                objFileStream = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write);
                objStreamWriter = new StreamWriter(objFileStream, System.Text.Encoding.Unicode);
                for (int i = 0; i < m_DataView.Columns.Count; i++)
                {
                    if (m_DataView.Columns[i].Visible == true)
                    {
                        strLine = strLine + m_DataView.Columns[i].HeaderText.ToString() + Convert.ToChar(9);
                    }
                }
                objStreamWriter.WriteLine(strLine);
                strLine = "";

                for (int i = 0; i < m_DataView.Rows.Count; i++)
                {
                    if (m_DataView.Columns[0].Visible == true)
                    {
                        if (m_DataView.Rows[i].Cells[0].Value == null)
                            strLine = strLine + " " + Convert.ToChar(9);
                        else
                            strLine = strLine + m_DataView.Rows[i].Cells[0].Value.ToString() + Convert.ToChar(9);
                    }
                    for (int j = 1; j < m_DataView.Columns.Count; j++)
                    {
                        if (m_DataView.Columns[j].Visible == true)
                        {
                            if (m_DataView.Rows[i].Cells[j].Value == null)
                                strLine = strLine + " " + Convert.ToChar(9);
                            else
                            {
                                string rowstr = "";
                                rowstr = m_DataView.Rows[i].Cells[j].Value.ToString();
                                if (rowstr.IndexOf("\r\n") > 0)
                                    rowstr = rowstr.Replace("\r\n", " ");
                                if (rowstr.IndexOf("\t") > 0)
                                    rowstr = rowstr.Replace("\t", " ");
                                strLine = strLine + rowstr + Convert.ToChar(9);
                            }
                        }
                    }
                    objStreamWriter.WriteLine(strLine);
                    strLine = "";
                }
                objStreamWriter.Close();
                objFileStream.Close();
                MessageBox.Show(this, "保存EXCEL成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        //导出excel
        private void button_SaveToExcel_Click(object sender, EventArgs e)
        {
            DataToExcel(dataGridView1);//导出excel
        }


        //在电脑桌面保存listbox中的文件
        private void SaveLstToTxt(ListBox lst)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "(*.txt)|*.txt";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string sPath = sfd.FileName;
                FileStream fs = new FileStream(sPath, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
                int iCount = lst.Items.Count - 1;
                for (int i = 0; i <= iCount; i++)
                {
                    sw.WriteLine(lst.Items[i].ToString());
                }
                sw.Flush();
                sw.Close();
                fs.Close();
            }
        }

        private void button_SaveToTxt_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "(*.txt)|*.txt|(*.*)|*.*";
            saveFileDialog.FileName = "文件" + DateTime.Now.ToString("yyyyMMddHHmm") + ".txt";
            //将日期时间作为文件名
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName, true);
                streamWriter.Write(this.RichtextBox_Recive.Text);
                streamWriter.Close();
            }
        }


        //获取设备信息
        private void buttonInformation_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                byte[] buffd = new byte[] { 0xff, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 };
                CRC_x.uchCRCHi = 0;
                CRC_x.uchCRCLo = 0;
                try
                {
                    buffd[0] = (byte)Convert.ToInt32(textBox_Device.Text, 16);
                    //crc16(buff);
                    buffd[6] = (byte)CRC_x.uchCRCHi;
                    buffd[7] = (byte)CRC_x.uchCRCLo;

                    SendData.DeviceCode = buffd[0];
                    SendData.FunctionCode = buffd[1];
                    SendData.Address = 0x0001;
                    ;

                    serialPort1.Write(buff, 0, 8);
                    ReceiveOverTimer.Start();
                    string Sendstr = "发送:";
                    foreach (byte x in buffd)
                    {
                        Sendstr += x.ToString("x2").ToUpper() + " ";
                    }
                    // richTextBoxInformation.Text = Sendstr;

                }
                catch (Exception ee)
                {
                    MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }


        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Environment.Exit(System.Environment.ExitCode);//强行关闭运行的线程
            //Process.GetCurrentProcess().Kill()
            //Application.ExitThread();
        }


        //显示时间
        private void show_time(object sender, EventArgs e)
        {
            this.text_TIME1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }



        //参数1：发送框参数  参数2:16进制选择参数  参数3：校验框选择参数 
        public void Get_sendx_tofinallystring(string textBox_send1, string checkHexorChar1, string comboBox_CRCFunction1)
        {

            //组帧:
            //获取textBox_sendx文本框的值                
            string textBox_send1_string = " ";//= textBox_send1.Text.ToString(); //textBox_send1为textBox控件的名称
            foreach (Control cs in groupBox11.Controls)
            {
                if (cs is TextBox && cs.Name.Equals(textBox_send1))
                {
                    textBox_send1_string = cs.Text.ToString();
                }

            }

            string textBox_send1_string_real = textBox_send1_string.Replace(" ", "");//先替换其中的空格等
            int a = 0;
            byte[] buffer = new byte[1024];

            foreach (Control cs in groupBox11.Controls)
            {
                if (cs is CheckBox && cs.Name.Equals(checkHexorChar1))
                {

                    if (((CheckBox)cs).Checked != true) //发送字符串
                    {
                        System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();
                        buffer = ASCII.GetBytes(textBox_send1_string_real); //字符串转化成了十进制的ascii

                        a = textBox_send1_string_real.Length;

                    }
                    else//发送16进制
                    { //计算要定义数组的长度值buff[a]。计算a的值 
                        foreach (Control cb in groupBox11.Controls)
                        {
                            if (cb is ComboBox && cb.Name.Equals(comboBox_CRCFunction1))
                            {
                                a = FuntionCode_CRC1(((ComboBox)cb).SelectedIndex, buffer, a, textBox_send1_string_real);
                            }
                        }

                    }

                }

            }


            byte[] buff = new byte[a];

            for (int i = 0; i < a; ++i)
            {
                buff[i] = buffer[i];

            }
            try
            {
                //组帧串口发出的数据              
                serialPort1.Write(buff, 0, a);
                //组帧串口软件显示发送内容                                    
                string Sendstr = "发送:";
                string Sendstr1 = "";
                foreach (Control cs in groupBox11.Controls)
                {
                    if (cs is CheckBox && cs.Name.Equals(checkHexorChar1))
                    {

                        if (((CheckBox)cs).Checked != true) //发送字符串
                        {

                            Sendstr1 = textBox_send1_string;//直接把得到的字符串显示出来，不需要其他处理

                            if (checkHexorChar.Checked != true)////发送字符串,显示字符串
                            {
                                Sendstr += textBox_send1_string;
                            }
                            else                               ////发送字符串,显示16进制
                            {
                                for (int i = 0; i < a; i++)
                                {

                                    Sendstr += buff[i].ToString("x") + " ";//字符串转化成了十六进制的ascii
                                }
                            }
                        }

                        else//发送16进制，发送区要回显
                        {
                            foreach (byte x in buff)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                            {
                                //Sendstr += x.ToString("x2").ToUpper() + " ";//将1变为01                             
                                Sendstr1 += x.ToString("x2").ToUpper() + " ";///发送区正常回显
                            }


                            if (checkHexorChar.Checked != true)//显示页面选择显示字符串
                            {
                                Sendstr += System.Text.Encoding.ASCII.GetString(buff);//byte型转字符串型
                            }
                            else//显示页面选择显示16进制
                            {

                                foreach (byte x in buff)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                                {
                                    Sendstr += x.ToString("x2").ToUpper() + " ";//将1变为01                             

                                }
                            }
                        }

                        if (Form1.showflag)//显示开始/停止显示
                        {
                            RichtextBox_Recive.SelectionColor = Color.Blue;
                            RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + Sendstr);  //添加文本                    
                            RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                            RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行
                            foreach (Control cr in groupBox11.Controls)
                            {
                                if (cr is TextBox && cr.Name.Equals(textBox_send1))
                                {
                                    cr.Text = Sendstr1;
                                }

                            }
                            //textBox_send1.Text = Sendstr1;
                            // textBox11.SetSelected(textBox11.Items.Count - 1, true);
                        }
                    }//end   if (cs is CheckBox && cs.Name.Equals(checkHexorChar1))
                }//end  foreach

            }//end   try
            catch (Exception ee)
            {
                MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }



        ////发送区1发送模块
        private void button_Send_Click_1(object sender, EventArgs e)
        {
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.灰;//收到数据闪灯
            //Thread.Sleep(300);
            Send_Data.button1_flag = 1;
            if (serialPort1.IsOpen)
            {
                string strname1 = "textBox_send1";
                string strname2 = "checkHexorChar1";
                string strname3 = "comboBox_CRCFunction1";
                Get_sendx_tofinallystring(strname1, strname2, strname3);
                this.pictureBox2.Image = Axxx_sprial.Properties.Resources.绿;//收到数据闪灯
            }
            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();
                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }

        private void button_Send_Click_2(object sender, EventArgs e)
        {
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.灰;//收到数据闪灯
            //Thread.Sleep(300);
            Send_Data.button2_flag = 1;
            if (serialPort1.IsOpen)
            {

                //组帧:
                //获取textBox_send2文本框的值  

                string strname1 = "textBox_send2";
                string strname2 = "checkHexorChar2";
                string strname3 = "comboBox_CRCFunction2";
                Get_sendx_tofinallystring(strname1, strname2, strname3);
                this.pictureBox2.Image = Axxx_sprial.Properties.Resources.绿;//收到数据闪灯
            }
            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();
                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }

        private void button_Send_Click_3(object sender, EventArgs e)
        {
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.灰;//收到数据闪灯
            //Thread.Sleep(300);
            Send_Data.button3_flag = 1;

            if (serialPort1.IsOpen)
            {

                string strname1 = "textBox_send3";
                string strname2 = "checkHexorChar3";
                string strname3 = "comboBox_CRCFunction3";
                Get_sendx_tofinallystring(strname1, strname2, strname3);
            this.pictureBox2.Image = Axxx_sprial.Properties.Resources.绿;//收到数据闪灯
            }

            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();
                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }
        //发送组帧命令
        private void button_Send_Click_4(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {

                string textBox_send1_string_real = "";//存放帧头+数据+校验+帧尾


                string textBox_send1_string1 = "";
                string textBox_send1_string_real1 = "";//存放帧头的字符串（去掉空格之后的数据）

                string textBox_send1_string3 = "";
                string textBox_send1_string_real3 = "";//存放帧尾的字符串（去掉空格之后的数据）

                string textBox_send1_string4 = "";
                string textBox_send1_string_real4 = "";//存放文本框的字符串（去掉空格之后的数据）
                //如果有帧头选中
                if (checkBox4.Checked == true)
                {
                    textBox_send1_string1 = textBox1.Text.ToString();//textBox1为帧头内容
                    textBox_send1_string_real1 = textBox_send1_string1.Replace(" ", "");//先替换其中的空格等
                }
                //如果有帧尾选中
                if (checkBox6.Checked == true)
                {
                    textBox_send1_string3 = textBox3.Text.ToString();//textBox3为帧尾内容
                    textBox_send1_string_real3 = textBox_send1_string3.Replace(" ", "");//先替换其中的空格等
                }
                //获取textBox_send4文本框的值
                textBox_send1_string4 = textBox_send4.Text.ToString(); //textBox_send4为为数据区内容
                textBox_send1_string_real4 = textBox_send1_string4.Replace(" ", "");//先替换其中的空格等

                //帧头+数据+校验+帧尾
                // textBox_send1_string_real = textBox_send1_string_real1  + textBox_send1_string_real4 + textBox_send1_string_real3;

                //创建一个要显示数据的数组，且数组的大小是由校验方式决定的
                int a = 0;
                int b = 0;
                int c = 0;
                //不校验时，
                if (comboBox_CRCFunction4.SelectedIndex == 0)
                {  //数据区字符串长度为：1
                    if (textBox_send1_string_real4.Length == 1)
                    {
                        a = textBox_send1_string_real4.Length;
                    }//数据区字符串长度为：多个且为偶数个
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 0))
                    {
                        a = textBox_send1_string_real4.Length / 2;//有几个“xx" 
                    }//数据区字符串长度为：多个且为奇数个
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 1))
                    {
                        a = (textBox_send1_string_real4.Length / 2 + 1);
                    }
                }
                //校验时，a要加出来校验码的位置
                else if ((comboBox_CRCFunction4.SelectedIndex == 3) || (comboBox_CRCFunction4.SelectedIndex == 4) || (comboBox_CRCFunction4.SelectedIndex == 7))
                { //sum 和 8crc
                    if (textBox_send1_string_real4.Length == 1)
                    {
                        a = textBox_send1_string_real4.Length;
                        a = a + 1;//+n是用来放校验位的
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 0))
                    {
                        a = textBox_send1_string_real4.Length / 2;//有几个“xx" 
                        a = a + 1;
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 1))
                    {
                        a = (textBox_send1_string_real4.Length / 2 + 1);
                        a = a + 1;
                    }
                }

                else if ((comboBox_CRCFunction4.SelectedIndex == 1) || (comboBox_CRCFunction4.SelectedIndex == 2))
                {//crc16
                    if (textBox_send1_string_real4.Length == 1)
                    {
                        a = textBox_send1_string_real4.Length;
                        a = a + 2;
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 0))
                    {
                        a = textBox_send1_string_real4.Length / 2;//有几个“xx" 
                        a = a + 2;
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 1))
                    {
                        a = (textBox_send1_string_real4.Length / 2 + 1);
                        a = a + 2;
                    }
                }

                else if ((comboBox_CRCFunction4.SelectedIndex == 6) || (comboBox_CRCFunction4.SelectedIndex == 5))
                {//crc32
                    if (textBox_send1_string_real4.Length == 1)
                    {
                        a = textBox_send1_string_real4.Length;
                        a += 4;
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 0))
                    {
                        a = textBox_send1_string_real4.Length / 2;//有几个“xx" 
                        a += 4;
                    }
                    else if ((textBox_send1_string_real4.Length > 1) & (textBox_send1_string_real4.Length % 2 == 1))
                    {
                        a = (textBox_send1_string_real4.Length / 2 + 1);
                        a += 4;
                    }
                }
                //计算b的值
                if (textBox_send1_string_real1.Length == 1)
                {
                    b = 1;
                }
                else if ((textBox_send1_string_real1.Length > 1) & (textBox_send1_string_real1.Length % 2 == 0))
                {
                    b = textBox_send1_string_real1.Length / 2;//有几个“xx" 
                }//数据区字符串长度为：多个且为奇数个
                else if ((textBox_send1_string_real1.Length > 1) & (textBox_send1_string_real1.Length % 2 == 1))
                {
                    b = (textBox_send1_string_real1.Length / 2 + 1);
                }
                //计算c的值
                if (textBox_send1_string_real3.Length == 1)
                {
                    c = 1;
                }
                else if ((textBox_send1_string_real3.Length > 1) & (textBox_send1_string_real3.Length % 2 == 0))
                {
                    c = textBox_send1_string_real3.Length / 2;//有几个“xx" 
                }//数据区字符串长度为：多个且为奇数个
                else if ((textBox_send1_string_real3.Length > 1) & (textBox_send1_string_real3.Length % 2 == 1))
                {
                    c = (textBox_send1_string_real3.Length / 2 + 1);
                }

                byte[] buff = new byte[a];//存放帧中间
                byte[] buff1 = new byte[b];//存放帧头
                byte[] buff2 = new byte[c];//存放帧尾

                try
                {
                    //每2个字符串转化为1个字符串
                    Deal_str(textBox_send1_string_real4, buff);//计算输入数据区有几个字节
                    Deal_str(textBox_send1_string_real1, buff1);//计算帧头有几个字节
                    Deal_str(textBox_send1_string_real3, buff2);//计算帧头有几个字节
                    FuntionCode_CRC1(comboBox_CRCFunction4.SelectedIndex, buff, a, textBox_send1_string_real4);//校验并在原报文基础上加上校验码 

                    byte[] buff3 = new byte[a + b + c];//存放帧头+帧尾+校验好的数据,a为校验之后的数据

                    for (int i = 0; i < b; ++i)//b帧头
                    {
                        buff3[i] = buff1[i];//把帧头数据放入要发送的数组
                    }
                    for (int i = b; i < (b + a); ++i)
                    {
                        buff3[i] = buff[i - b];//把中间数据放入要发送的数组
                    }
                    for (int i = b + a; i < (b + c + a); ++i)//c帧尾
                    {
                        buff3[i] = buff2[i - b - a];//把帧尾数据放入要发送的数组
                    }

                    //组帧串口发出的数据

                    serialPort1.Write(buff3, 0, buff3.Length);

                    //组帧串口软件显示发送内容                                    
                    // string Sendstr = "发送:";
                    string Sendstr2 = "发送:";//回显帧头+帧尾+校验好的数据

                    string Sendstr1 = "";//用于回显在输入框中,buff存放校验好的数据
                    foreach (byte x in buff)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                    {
                        Sendstr1 += x.ToString("x2").ToUpper() + " ";
                    }
                    textBox_send4.Text = Sendstr1;//发送区检验完之后回显在发送区,buff3//存放帧头+帧尾+校验好的数据
                    foreach (byte x in buff3)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                    {
                        Sendstr2 += x.ToString("x2").ToUpper() + " ";
                    }
                    if (Form1.showflag)//显示开始/停止显示
                    {
                        RichtextBox_Recive.SelectionColor = Color.Blue;//发送区字体颜色
                        RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + Sendstr2);  //添加文本                    
                        RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                        RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行  
                    }
                }

                catch (Exception ee)
                {
                    MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();

                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }
        public delegate void senddata(byte[] data);
        public event senddata sendss;

        // sendss = new senddata(fm.ssss);                
        // sendss(buff);        



        void button_Send_Click(string str, EventArgs e)
        {
            Send_Data.button1_flag = 1;//发送按钮按下标志
            if (serialPort1.IsOpen)
            {
                //组帧:
                //获取textBox_send1文本框的值
                str = textBox_send1.Text.ToString(); //textBox_send1为textBox控件的名称

                string textBox_send1_string_real = str.Replace(" ", "");//先替换其中的空格等

                int a = 1;
                byte[] buffer = new byte[1024];
                if (checkHexorChar1.Checked != true) //发送字符串
                {
                    System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();
                    buffer = ASCII.GetBytes(textBox_send1_string_real); //字符串转化成了十进制的ascii                   
                    a = textBox_send1_string_real.Length;
                }
                else//发送16进制
                {  //计算要定义数组的长度值buff[a]。计算a的值
                    a = FuntionCode_CRC1(comboBox_CRCFunction1.SelectedIndex, buffer, a, textBox_send1_string_real);
                }

                byte[] buff = new byte[a];
                for (int i = 0; i < a; ++i)
                {
                    buff[i] = buffer[i];
                }
                try
                {
                    //组帧串口发出的数据              
                    serialPort1.Write(buff, 0, a);
                    if (checkBox_LoopSend1.Checked)//是否循环发送
                    {
                        Looptimer1.Start();
                    }
                    //组帧串口软件显示发送内容                                    
                    string Sendstr = "发送:";//用于显示区回显
                    string Sendstr1 = "";//用于发送区回显
                    if (checkHexorChar1.Checked != true) //发送字符串
                    {
                        Sendstr1 = str;//直接把得到的字符串显示出来，不需要其他处理

                        if (checkHexorChar.Checked != true)////发送字符串,显示字符串
                        {
                            Sendstr += str;
                        }
                        else                               ////发送字符串,显示16进制
                        {
                            for (int i = 0; i < a; i++)
                            {
                                Sendstr += buff[i].ToString("x") + " ";//字符串转化成了十六进制的ascii
                            }
                        }
                    }
                    else//发送16进制，发送区要回显
                    {
                        foreach (byte x in buff)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                        {
                            Sendstr1 += x.ToString("x2").ToUpper() + " ";///发送区正常回显
                        }
                        if (checkHexorChar.Checked != true)//显示页面选择显示字符串
                        {
                            Sendstr += System.Text.Encoding.ASCII.GetString(buff);//byte型转字符串型

                        }
                        else//显示页面选择显示16进制
                        {
                            foreach (byte x in buff)//逐个遍历str_real中的每个字符,赋给x,直到str中数据全部都被遍历了一遍
                            {
                                Sendstr += x.ToString("x2").ToUpper() + " ";//将1变为01                                                           
                            }
                        }
                    }

                    RichtextBox_Recive.SelectionColor = Color.Blue;
                    RichtextBox_Recive.AppendText("[" + DateTime.Now.ToString() + "]" + Sendstr);  //添加文本
                    RichtextBox_Recive.AppendText(System.Environment.NewLine);//换行
                    RichtextBox_Recive.ScrollToCaret();    //自动显示至最后行
                    // listBox11.SetSelected(listBox11.Items.Count - 1, true);                    
                }
                catch (Exception ee)
                {
                    MessageBox.Show(this, ee.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                Looptimer.Stop();
                Looptimer1.Stop();
                Looptimer2.Stop();
                Looptimer3.Stop();
                ReceiveOverTimer.Stop();

                // SerialStatusButton.Text = "打开";
                // SerialPortComboBox.Enabled = true;
                // BaudRateComboBox.Enabled = true;
                // SerialPortScanButton.Enabled = true;
                // StatusText1.Text = "串口关闭。";
                button_Send.Enabled = false;
                MessageBox.Show(this, "请打开串口", "提示");
            }
        }
        //清空文本1
        private void button_clear_0(object sender, EventArgs e)
        {
            Thread.Sleep(200);
            RichtextBox_Recive.Clear();//清空文本
        }
        //清空文本2
        private void button_clear_1(object sender, EventArgs e)
        {
            textBox_send1.Clear();//清空文本
            //textBox1.Text="";//文本为空
        }

        //清空文本3
        private void button_clear_2(object sender, EventArgs e)
        {
            textBox_send2.Clear();//清空文本
            //textBox1.Text="";//文本为空
        }
        //清空文本4
        private void button_clear_3(object sender, EventArgs e)
        {
            textBox_send3.Clear();//清空文本
        }

        private void 串口通信ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.panel2.Visible = true;//串口
            this.panel1.Visible = false;
            panel2.BringToFront(); //Panel2显示
        }

        private void 网口通信ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            panel1.Location = panel2.Location;//让位置相等
            this.panel1.Visible = true;//网口设置页面打开
            this.panel2.Visible = false;
            panel1.BringToFront(); //Panel1显示
        }

        //弹窗:帮助
        private void ToolStripMenuItem_help_Click(object sender, EventArgs e)
        {
            Form4 fm = new Form4();
            //设置子窗体出现位置
            fm.StartPosition = FormStartPosition.CenterScreen;
            fm.Show();

        }
        //弹窗:ASCII表
        private void aSCII表ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form3 fm = new Form3();
            //设置子窗体出现位置
            fm.StartPosition = FormStartPosition.CenterScreen;
            fm.Show();
        }

        //弹窗:色环电阻计算表
        private void 电阻色环计算器ToolStripMenuItem_click(object sender, EventArgs e)
        {
            Form2 fm = new Form2();
            //设置子窗体出现位置
            fm.StartPosition = FormStartPosition.CenterScreen;
            fm.Show();

        }


        private void 待升级记录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 fm = new Form5();

            fm.StartPosition = FormStartPosition.CenterScreen;
            fm.Show();
        }
        //不弹出支持这个页面，太俗了
        private void 支持ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form6 fm = new Form6();

            fm.StartPosition = FormStartPosition.CenterScreen;
            fm.Show();
        }
        //百度
        private void 百度ToolStripMenuItem_click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.baidu.com");
        }
        //计算器
        private void jisuanqi_Click(object sender, EventArgs e)
        {
            System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
            Info.FileName = "calc.exe ";//"calc.exe"为计算器
            System.Diagnostics.Process Proc = System.Diagnostics.Process.Start(Info);
        }
        //记事本
        private void jishiben_Click(object sender, EventArgs e)
        {
            System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
            Info.FileName = "notepad.exe";//"notepad.exe"为记事本
            System.Diagnostics.Process Proc = System.Diagnostics.Process.Start(Info);
        }

        //更改字体颜色
        private void Button_color(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            if (cd.ShowDialog() == DialogResult.OK)
            {
                RichtextBox_Recive.SelectionColor = cd.Color;
            }
        }
        //更改字体大小
        private void Button_Fontsize(object sender, EventArgs e)
        {
            FontDialog ff = new FontDialog();
            if (ff.ShowDialog() == DialogResult.OK)
            {
                RichtextBox_Recive.Font = ff.Font;
            }
        }
        //更改背景颜色
        private void 背景颜色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            if (cd.ShowDialog() == DialogResult.OK)
            {
                RichtextBox_Recive.BackColor = cd.Color;
            }
        }

        //显示框显示16进制控制
        private void checkHexorChar_CheckedChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                //SerialPortOpen();
            }
        }
        // 数据解析控制
        private void checkBox1_jiexi_CheckedChange(object sender, EventArgs e)
        {
            if (checkBox1_jiexi.Checked == true)
            {
                timer1.Enabled = true;//启动示波器
            }
            else timer1.Enabled = false;//关闭示波器
        }
        //发送框1显示16进制控制
        private void checkHexorChar1_CheckedChanged(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                SerialPortOpen();
            }
        }
        //发送框2显示16进制控制
        private void checkHexorChar2_CheckedChanged(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                SerialPortOpen();
            }
        }
        //发送框3显示16进制控制
        private void checkHexorChar3_CheckedChanged(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                SerialPortOpen();
            }


        }


        //、、、、、、、、、、、、、、、、分界线、、、、、、、、、、、、、、、、、、、、、、、、、、、、、//



        //用于通信的Socket
        Socket socketSend;
        //用于监听的SOCKET
#pragma warning disable CS0169 // 从不使用字段“Form1.socketWatch”
        Socket socketWatch;
#pragma warning restore CS0169 // 从不使用字段“Form1.socketWatch”
        //将远程连接的客户端的IP地址和Socket存入集合中
        Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

        //监听/连接按钮
        public void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;//按钮按下去不可以按
            if (Serive_type.SelectedIndex == 0) //服务端
            {
                try
                {
                    //当点击开始监听的时候 在服务器端创建一个负责监IP地址跟端口号的Socket
                    Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //IPAddress ip = IPAddress.Any;//
                    IPAddress ip = IPAddress.Parse(txtServer.Text);
                    //创建端口号对象
                    IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

                    socketWatch.Bind(point);  //绑定端口号                 
                    btnStart.Text = "监听成功";
                    socketWatch.Listen(10);//设置监听

                    //开启一个新的线程不停的接收服务端发来的消息
                    Thread thread = new Thread(Listen);
                    thread.IsBackground = true;
                    thread.Start(socketWatch);
                }
                catch
                { }
            }
            if (Serive_type.SelectedIndex == 1) //客户端
            {
                btnStart.Text = "准备连接";
                try
                {
                    //创建负责通信的Socket,获得远程ip和端口号
                    socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPAddress ip = IPAddress.Parse(txtServer.Text);
                    IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
                    //获得要连接的远程服务器应用程序的IP地址和端口号
                    socketSend.Connect(point);
                    btnStart.Text = "连接成功";
                    //开启一个新的线程不停的接收服务端发来的消息
                    Thread th = new Thread(Recive2);
                    th.IsBackground = true;
                    th.Start();
                }
                catch
                {
                    //ShowMsg("IP或者端口号错误..."); 
                }

            }
        }
        //断开连接按钮
        private void button6_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = true;//按钮按下去不可以按
        }



        void Listen(object o) // 等待客户端的连接 并且创建与之通信用的Socket
        {
            try
            {
                Socket socketWatch = o as Socket;
                //等待客户端的连接 并且创建一个负责通信的Socket
                while (true)
                {
                    socketSend = socketWatch.Accept();//负责跟客户端通信的Socket             
                    //dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend); //将远程连接的客户端的IP地址和Socket存入集合中
                    //将远程连接的客户端的IP地址和端口号存储下拉框中
                    //comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString());
                    //192.168.11.78：连接成功
                    ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");
                    Thread th = new Thread(Recive); //开启一个新线程不停的接受客户端发送过来的消息
                    th.IsBackground = true;
                    th.Start(socketSend);
                }
            }
            catch { }

        }



        //客户端不断接
        // 服务器端不停的接受客户端发送过来的消息      
        void Recive(object o)
        {
            try
            {
                Socket socketSend = o as Socket;
                while (true)
                {

                    //客户端连接成功后，服务器应该接受客户端发来的消息
                    byte[] buffer = new byte[1024 * 1024 * 3];
                    //实际接受到的有效字节数
                    int len = socketSend.Receive(buffer);
                    if (len == 0)
                    {
                        //    foreach (byte x in buffer)//赋给x,直到str中数据全部都被遍历了一遍
                        //    {

                        //        textBox4.Text  += x.ToString("x2").ToUpper() + " ";///发送区正常回显
                        //    }

                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, len);
                    ShowMsg(socketSend.RemoteEndPoint + ":" + str);//哪个ip发的什么数据
                }
            }
            catch { }

        }


        void Send(string str)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(str);
            socketSend.Send(buffer);
        }
        // 服务器给客户端发送消息
        void ShowMsg(string str)
        {
            String Readstr = "";
            // txtLog.AppendText(str + "\r\n");
            Readstr = str.ToString().ToUpper() + " ";
            Rich_text_receive2.SelectionColor = Color.Red;//字体颜色
            Rich_text_receive2.AppendText("[" + DateTime.Now.ToString() + "]" + "接收:" + Readstr);  //添加文本                    
            Rich_text_receive2.AppendText(System.Environment.NewLine);//换行
            Rich_text_receive2.ScrollToCaret();    //自动显示至最后行
        }

        //private void Form1_Load(object sender, EventArgs e)
        //{
        //    Control.CheckForIllegalCrossThreadCalls = false;
        //}
        //给客户端发消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            Send(Text_TCPsend.Text.Trim());
        }


        //private void btnSend_Click(object sender, EventArgs e)
        //    {
        //        string str = txtLog.Text;
        //        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
        //        List<byte> list = new List<byte>();
        //        list.Add(0);
        //        list.AddRange(buffer);
        //        //将泛型集合转换为数组
        //        byte[] newBuffer = list.ToArray();
        //        //buffer = list.ToArray();不可能
        //        //获得用户在下拉框中选中的IP地址
        //        string ip = txtServer.ToString();
        //        dicSocket[ip].Send(newBuffer);
        //             //socketSend.Send(buffer);
        //    }



        /// <summary>
        /// 选择要发送的文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
            ofd.Title = "请选择要发送的文件";
            ofd.Filter = "所有文件|*.*";
            ofd.ShowDialog();

            Text_TCPsend.Text = ofd.FileName;//获得要发送文件的全路径
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            //获得要发送文件的路径
            string path = Text_TCPsend.Text;
            using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[1024 * 1024 * 5];
                int r = fsRead.Read(buffer, 0, buffer.Length);
                List<byte> list = new List<byte>();
                list.Add(1);
                list.AddRange(buffer);
                byte[] newBuffer = list.ToArray();
                //注意：因为要多发一个字节，所有发送字节数为r+1
                dicSocket[txtServer.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);

            }
        }


        /// <summary>
        /// 不停的接受服务器发来的消息
        /// </summary>
        void Recive2()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024 * 1024 * 3];
                    int len = socketSend.Receive(buffer);
                    //实际接收到的有效字节数
                    if (len == 0)
                    {
                        break;
                    }
                    //表示发送的文字消息
                    if (buffer[0] == 0)
                    {
                        string s = Encoding.UTF8.GetString(buffer, 1, len - 1);
                        ShowMsg(socketSend.RemoteEndPoint + ":" + s);
                    }
                    else if (buffer[0] == 1)
                    {
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
                        sfd.Title = "请选择要保存的文件";
                        sfd.Filter = "所有文件|*.*";
                        sfd.ShowDialog(this);
                        string path = sfd.FileName;
                        using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            fsWrite.Write(buffer, 1, len - 1);
                        }
                        MessageBox.Show("保存成功");
                    }
                    else if (buffer[0] == 2)
                    {

                    }

                    string str = Encoding.UTF8.GetString(buffer, 0, len);
                    ShowMsg(socketSend.RemoteEndPoint + ":" + str);

                }
                catch { }

            }
        }

        //给服务器发送消息
        private void btnSend_Click2(object sender, EventArgs e)
        {
            try
            {
                string str = Text_TCPsend.Text.Trim();
                byte[] buffer = new byte[1024 * 1024 * 3];
                buffer = System.Text.Encoding.UTF8.GetBytes(str);
                socketSend.Send(buffer);
            }
            catch { }

        }

        private void 待定2ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Click(object sender, EventArgs e)
        {
        }




        private void 关闭软件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }
        //程序更新
        public static bool checkUpdateLoad()
        {
            bool result = false;
            SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "Axxx_Com");

            try
            {
                if (app.IsUpdate && MessageBox.Show("检查到新版本，是否更新？", "Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {

                    string path = Application.StartupPath.Replace("program", "");
                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName = "WindowsFormsApplication1.exe";
                    process.StartInfo.WorkingDirectory = path;//要调用得exe路径例如:"C:\windows";               
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();//调用自动更新程序
                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

            }
            return result;
        }


        private void check_updata_click(object sender, EventArgs e)
        {
            //checkUpdateLoad
            if (checkUpdateLoad())//调用上面函数
            {
                Application.Exit();
                return;
            }
            else 
            { 
                MessageBox.Show("   已是新版本v1.1");
            }
           
        }

        private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void groupBox6_Enter(object sender, EventArgs e)
        {

        }

        private void groupBox4_Enter(object sender, EventArgs e)
        {

        }

        private void label23_Click(object sender, EventArgs e)
        {

        }

        private void label24_Click(object sender, EventArgs e)
        {

        }

        private void label25_Click(object sender, EventArgs e)
        {

        }

        private void label27_Click(object sender, EventArgs e)
        {

        }

        private void label26_Click(object sender, EventArgs e)
        {

        }

        private void label28_Click(object sender, EventArgs e)
        {

        }

        private void label29_Click(object sender, EventArgs e)
        {

        }
       
      
      
       
      

      

    }
}

